﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace CodeAnalyzer.Engine
{
    public class Engine
    {
        string xmlPath = "configCommands.xml";

        public string GetInfoFacade(string fileDirectory, string language)
        {
            string report = string.Empty;
            Parser.LanguageParser languageParser = new Parser.LanguageParser();

            List<Command> commands = new List<Command>();
            List<string> files = searchFileSystem(".frm", fileDirectory.Substring(0, fileDirectory.LastIndexOf('\\')));
            files.AddRange(searchFileSystem(".bas", fileDirectory.Substring(0, fileDirectory.LastIndexOf('\\'))).ToArray());
            files.AddRange(searchFileSystem(".cls", fileDirectory.Substring(0, fileDirectory.LastIndexOf('\\'))).ToArray());
            string [] items = GetFileContent(fileDirectory).Split('\n');
            for (int iItems = 0; iItems < items.Length; iItems++)
            {
                if (items[iItems].IndexOf("Reference") == 0 || items[iItems].IndexOf("Object") == 0)
                {
                    report += items[iItems] +"\r\n";
                }
            }

            for (int iCont = 0; iCont < files.Count; iCont++)
            {
                commands.AddRange(languageParser.Parse(GetFileContent(files[iCont]), GetLanguage(language)).ToArray());
            }

            report = "Total Line Number:" + languageParser.TotalLinesCount.ToString() +"\r\n" + report;
            
            XmlSerializer x = new XmlSerializer(commands.GetType());
            System.IO.StreamWriter sw = new System.IO.StreamWriter("result.xml");
            x.Serialize(sw, commands);
            sw.Close();
            sw.Dispose();
            StreamReader sr = new StreamReader("result.xml");
            report += sr.ReadToEnd();
            sr.Close();
            sr.Dispose();
            return report;
        }

        private string GetFileContent(string fileDirectory)
        {
            System.IO.StreamReader str = new System.IO.StreamReader(fileDirectory);
            string result = str.ReadToEnd();
            str.Close();
            str.Dispose();
            return result;
        }

        private List<Command> GetLanguage(string language)
        {
            List<Command> languageInfo = new List<Command>();

            XmlDocument document = new XmlDocument();
            document.Load(xmlPath);

            for (int iLanguages = 0; iLanguages < document.ChildNodes[0].ChildNodes.Count; iLanguages++)
            {
                if (document.ChildNodes[0].ChildNodes[iLanguages].Attributes["name"].Value == language)
                {
                    for (int iCommand = 0; iCommand < document.ChildNodes[0].ChildNodes[iLanguages].ChildNodes.Count; iCommand++)
                    {
                        if (document.ChildNodes[0].ChildNodes[iLanguages].ChildNodes[iCommand].Name == "command")
                        {
                            Command cmd = new Command();
                            cmd.Name = document.ChildNodes[0].ChildNodes[iLanguages].ChildNodes[iCommand].Attributes["name"].Value;
                            cmd.Syntax = document.ChildNodes[0].ChildNodes[iLanguages].ChildNodes[iCommand].Attributes["name"].Value;
                            cmd.OpenCommand = document.ChildNodes[0].ChildNodes[iLanguages].ChildNodes[iCommand].Attributes["opencommand"].Value;
                            cmd.CloseCommand = document.ChildNodes[0].ChildNodes[iLanguages].ChildNodes[iCommand].Attributes["closecommand"].Value;
                            cmd.Level = int.Parse(document.ChildNodes[0].ChildNodes[iLanguages].ChildNodes[iCommand].Attributes["level"].Value);
                            languageInfo.Add(cmd);
                        }
                    }
                }
            }
            

            return languageInfo;
        }


        public List<string> searchFileSystem(string searchPattern, string fileInitialPath)
        {
            return searchFileSystem(searchPattern, fileInitialPath, "");
        }
        public List<string> searchFileSystem(string searchPattern, string fileInitialPath, string extension)
        {
            List<string> result = new List<string>();
            DirectoryInfo directory = new DirectoryInfo(fileInitialPath);
            searchPattern = "*" + searchPattern.Replace(" ", "*") + "*";
            if (extension != string.Empty)
                searchPattern += extension;
            result = searchFile(searchPattern, directory, result);
            return result;
        }

        private List<string> searchFile(string searchPattern, DirectoryInfo directory, List<string> result)
        {
            try
            {
                FileInfo[] files = directory.GetFiles(searchPattern);
                for (int iFile = 0; iFile < files.Length; iFile++)
                {
                    result.Add(files[iFile].FullName);
                }

                DirectoryInfo[] directories = directory.GetDirectories();
                for (int iFolder = 0; iFolder < directories.Length; iFolder++)
                {
                    result = searchFile(searchPattern, directories[iFolder], result);
                }
            }
            catch
            {
            }
            finally
            {
                //Não precisa de catch pois não haverá tratamento, só vai trazer resultado de pesquisa.
            }

            return result;
        }

    }
}
